package ar.com.photo_admin.login

import grails.converters.JSON

import javax.servlet.http.HttpServletResponse

import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils

import org.springframework.security.authentication.AccountExpiredException
import org.springframework.security.authentication.CredentialsExpiredException
import org.springframework.security.authentication.DisabledException
import org.springframework.security.authentication.LockedException
import org.springframework.security.core.context.SecurityContextHolder as SCH
import org.springframework.security.web.WebAttributes
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
import org.springframework.security.web.savedrequest.SavedRequest

import ar.com.photo_admin.domain.User
import ar.com.photo_admin.service.security.FacebookService
import ar.com.photo_admin.domain.Utils

import grails.plugins.springsecurity.Secured

class LoginController {

	/**
	 * Dependency injection for the authenticationTrustResolver.
	 */
	def authenticationTrustResolver

	/**
	 * Dependency injection for the springSecurityService.
	 */
	def springSecurityService
	
	/**
	 * Dependency injection for the captchaCodeService.
	 */
	def captchaCodeService
	
	/**
	 * Dependency injection for the userService.
	 */
	def userService
	
	/**
	 * Dependency injection for the facebookService.
	 */
	def facebookService
	
	/**
	 * Default action; redirects to 'defaultTargetUrl' if logged in, /login/auth otherwise.
	 */
	def index = {
		if (springSecurityService.isLoggedIn()) {
			redirect uri: SpringSecurityUtils.securityConfig.successHandler.defaultTargetUrl
		}
		else {
			redirect action: 'auth', params: params
		}
	}

	/**
	 * Show the login page.
	 */
	def auth = {

		def config = SpringSecurityUtils.securityConfig

		if (springSecurityService.isLoggedIn()) {
			redirect uri: config.successHandler.defaultTargetUrl
			return
		}

		forward(controller: "index", action: "login")
	}

	/**
	 * The redirect action for Ajax requests.
	 */
	def authAjax = {
		
		session.putAt(WebAttributes.SAVED_REQUEST, null);
		response.sendError HttpServletResponse.SC_UNAUTHORIZED
	}

	/**
	 * Show denied page.
	 */
	def denied = {
		if (springSecurityService.isLoggedIn() &&
				authenticationTrustResolver.isRememberMe(SCH.context?.authentication)) {
			// have cookie but the page is guarded with IS_AUTHENTICATED_FULLY
			redirect action: 'full', params: params
		}
	}

	/**
	 * Login page for users with a remember-me cookie but accessing a IS_AUTHENTICATED_FULLY page.
	 */
	def full = {
		def config = SpringSecurityUtils.securityConfig
		render view: 'auth', params: params,
			model: [hasCookie: authenticationTrustResolver.isRememberMe(SCH.context?.authentication),
			        postUrl: "${request.contextPath}${config.apf.filterProcessesUrl}"]
	}

	/**
	 * Callback after a failed login. Redirects to the auth page with a warning message.
	 */
	def authfail = {

		def username = session[UsernamePasswordAuthenticationFilter.SPRING_SECURITY_LAST_USERNAME_KEY]
		String msg = ''
		def exception = session[WebAttributes.AUTHENTICATION_EXCEPTION]
		if (exception) {
			if (exception instanceof AccountExpiredException) {
				msg = g.message(code: "springSecurity.errors.login.expired")
			}
			else if (exception instanceof CredentialsExpiredException) {
				msg = g.message(code: "springSecurity.errors.login.passwordExpired")
			}
			else if (exception instanceof DisabledException) {
				msg = g.message(code: "springSecurity.errors.login.disabled")
			}
			else if (exception instanceof LockedException) {
				msg = g.message(code: "springSecurity.errors.login.locked")
			}
			else {
				msg = g.message(code: "springSecurity.errors.login.fail")
			}
		}

		if (springSecurityService.isAjax(request)) {
			render([error: msg] as JSON)
		}
		else {
			flash.message = msg
			redirect action: 'auth', params: params
		}
	}

	/**
	 * The Ajax success redirect url.
	 */
	def ajaxSuccess = {
		render([success: true, username: springSecurityService.authentication.name] as JSON)
	}

	/**
	 * The Ajax denied redirect url.
	 */
	def ajaxDenied = {
		render([error: 'access denied'] as JSON)
	}
	
	/**
	 * Create a user and automatically login 
	 */
	def siteSignin() {
		signIn("siteSignin")
	}
	
	private def signIn(String templateId) {
		
		User user = new User()
		
		user.properties = params
		user.confirmPassword = params.confirmPassword
		user.captchaCode = params.captchaCode
		
		user.validate()
				
		boolean captchaValid = captchaCodeService.validateCaptcha(user)
		
		if (captchaValid && userService.save(user)) {
			springSecurityService.reauthenticate(user.username)
			
			/*
			 * if the user try to access a secure page then he should be redirect to that page
			 */
			def redirectUrl = session.getAttribute(WebAttributes.SAVED_REQUEST)?.getRedirectUrl()
			render Utils.reload_page_on_ajax_response(redirectUrl)
		} else {
			user.password = ""
			user.confirmPassword = ""
			user.captchaCode = ""
			render(template: templateId, model: [user: user])
		}
	}
	
	def facebookSignin() {
		
		def profile = facebookService.getProfileByFacebookUidUsingSession()
		params.facebookUid = profile.id
		
		println profile
		
		signIn("facebookSignin")
	}
	
	@Secured(['ROLE_ADMIN'])
	def adminLogin() {
	}
	
	@Secured(['ROLE_ADMIN'])
	def proccessAdminLogin() {
		def username = params.j_username
		springSecurityService.reauthenticate(username)
		
		redirect(url: "/")
	}
}
